package com.tencent.welink.iot;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.leaf.lowcode.utils.RegularInstance;
import com.tencent.welink.sm.SM4Utils;
import com.tencent.welink.util.CrontabUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.eclipse.paho.client.mqttv3.MqttException;

import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicLong;

/**
 * Created by limye on 2020/7/7.
 */
public class WelinkHttpReceive {
    private static final Logger log = LogManager.getLogger(WelinkHttpReceive.class);
    private final LoginData loginData;
    private WelinkHttp welinkHttp;
    private boolean change = false;
    WelinkHttpPull welinkHttpPull = new WelinkHttpPull();
    private AtomicLong seq = new AtomicLong(0);
    private String url;
    private String wId;

    public WelinkHttpReceive(WelinkHttp welinkHttp, String url, String wId) {
        this.welinkHttp = welinkHttp;
        loginData = welinkHttp.loginData;
        this.url = url;
        this.wId = wId;
    }

    /**
     * 定时拉取数据
     */
    public void
    schedulePullData() {
        CrontabUtil.addTaskInRate(() -> {
            pullMsg();
        }, 60 * 1000, true);
    }

    /**
     * 拉取消息
     */
    public void pullMsg() {
        welinkHttpPull.getHeaderPara().put("wId", wId);
        welinkHttpPull.getHeaderPara().put("token", loginData.httpToken);
        byte[] result = welinkHttpPull.doResultByHttpGet(url + "?seq=" + seq.getAndIncrement());
        try {
            decryptPayLoad(result);
        } catch (Exception e) {
            log.error("decryptPayLoad error:", e);
        }
    }

    private void changeToken() {
        log.info("chanage token {} from to {} token", this.loginData.lastHttpToken, this.loginData.httpToken);
        this.loginData.lastHttpToken = this.loginData.httpToken;
        this.loginData.lastRan = this.loginData.ran;
        this.loginData.lastSm4IV = this.loginData.sm4IV;
        this.change = true;
        log.info("after chanage token {} from to {} token", this.loginData.lastHttpToken, this.loginData.httpToken);
    }

    private void caseJsonProcess(JSONObject jsonObject) {
        int datapoint = jsonObject.getIntValue("datapoint");
        if (datapoint == 10000084) {
            log.info("video command here ...");
            JSONObject jsonValue = JSONObject.parseObject(jsonObject.getString("value"));
            long din = Long.parseLong((String) jsonObject.get("subDin"));
//            this.handleVideoCmd(din, jsonValue);
        } else if (datapoint == 30006) {
            log.info("sub device list received ...");
            this.handleReceiveSubDeviceList(jsonObject);
        } else if (datapoint == -1) {
            log.info("device passthrough data...");
            JSONObject jsonValue = JSONObject.parseObject(jsonObject.getString("value"));
            long din = Long.parseLong((String) jsonObject.get("subDin"));
            this.handleDevicePassThrough(din, jsonValue);
        } else if (datapoint == 100) {
            log.info("device receive data =====================  ");
            JSONObject jsonValue = JSONObject.parseObject(jsonObject.getString("value"));
            log.info("jsonValue" + jsonValue);
        }
    }

    private void decryptPayLoad(byte[] result) throws Exception {
        if (result == null || result.length == 0) {
            return;
        }
        LoginData ld = loginData.load();
        try {
            String message = new String(SM4Utils.decryptDataCBC(result, ld.ran, ld.sm4IV), "utf-8");
            log.info(System.currentTimeMillis() + "接收消息内容 : " + message);

            JSONObject jsonObject = JSONObject.parseObject(message);
            caseJsonProcess(jsonObject);

            if (!change)
                changeToken();
        } catch (Exception e) {
            log.error(e);
        }
    }


    /**
     * 处理接受子设备列表
     *
     * @param jsonObject
     */
    public void handleReceiveSubDeviceList(JSONObject jsonObject) {
        /**
         * [{"nvrusername":"","ipc_manufacturer":"","ip":"","nvrpassword":"","din":"300000000000070688",
         * "channel":0,"pid":1701000276,"rtspuri":"","nvrport":0,"manufacturer":"lim","password":"123",
         * "stream_from":"","wId":"139df654-a6f8-4dbf-8071-dafac7c943d9","nvrip":"","subdin":"0","port":0,
         * "nvr_manufacturer":"","sn":"1701000276lim","username":"admin"},
         * {"nvrusername":"","ipc_manufacturer":"","ip":"","nvrpassword":"","din":"300000000000070689",
         * "channel":0,"pid":1701000276,"rtspuri":"","nvrport":0,"manufacturer":"lim","password":"admin",
         * "stream_from":"","wId":"08338d42-75f9-4cde-ab27-7272fd9b0826","nvrip":"","subdin":"0","port":0,
         * "nvr_manufacturer":"","sn":"1701000276lim2","username":"123"}]
         */
        String deviceArray = (String) jsonObject.get("value");
        System.out.println("egularInstance.subDeviceDTOList======");
        if (StringUtils.isNotEmpty(deviceArray)) {
            JSONArray jsonArray = JSONArray.parseArray(deviceArray);
            ArrayList<SubDeviceDTO> deviceDTOS = (ArrayList<SubDeviceDTO>) jsonArray.toJavaList(SubDeviceDTO.class);
            this.welinkHttp.subDeviceDTOList = deviceDTOS;

            RegularInstance.subDeviceDTOList = deviceDTOS;  //存入静态变量或写入数据库
        }
    }

    /**
     * 设备透传
     *
     * @param subDin
     * @param jsonValue
     */
    public void handleDevicePassThrough(long subDin, JSONObject jsonValue) {
        try {
            int datapoint = jsonValue.getIntValue("datapoint");
            String value = jsonValue.getString("value");
            welinkHttp.sendMessage(loginData.ran, loginData.sm4IV, datapoint, subDin, value, "report");
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }

//    /**
//     * 处理推流
//     *
//     * @param jsonObject
//     */
//    public void handleVideoCmd(long din, JSONObject jsonObject) {
//        /**
//         * {"sm4_vector":"fEMVTDdskElB7lN9","stream_token":"Xwz43pHT","stream_id":0,
//         * "stream_en_key":"a0PtcFylyWnSh1UY","server_ip":"118.126.104.117","server_port":9001,
//         * "cmd":"StartPushStream","encrypt_version":4,"server_innerip":"10.3.32.12"}
//         *
//         * o.put("din", din);
//         o.put("subdin", 0);
//         o.put("stream_id", streamId);
//         o.put("stream_token",token);
//         o.put("server_ip",videoServerJo.get("outip"));
//         o.put("server_innerip",videoServerJo.getString("videoPushServerIp"));
//         o.put("server_port",videoServerJo.getInteger("port"));
//         o.put("cmd", "StartPushStream");
//         o.put("timeStamp",System.currentTimeMillis());
//         *
//         */
//        int subdin = 0;
//        int streamId = jsonObject.getIntValue("stream_id");
//        String key = din + "_" + subdin + "_" + streamId;
//        String stream_en_key = jsonObject.getString("stream_en_key");
//        String sm4Vector = jsonObject.getString("sm4_vector");
//        String token = jsonObject.getString("stream_token");
//        String host = jsonObject.getString("server_ip");
//        String innerip = jsonObject.getString("server_innerip");
//        int port = jsonObject.getIntValue("server_port");
//        String cmd = jsonObject.getString("cmd");
//
//
//        String recordHandler = (String) jsonObject.get("recordHandler");
//        //  String filePath = NVRSenderClient.class.getResource("/").getPath()+"default.mtav";
//        // String filePath = "D:\\04src\\welink\\welink-sdk\\welink-java-sdk\\src\\main\\resources\\default.mtav";
//        String filePath = NVRSenderClient.class.getResource("/"+BussinessConfig.videoFileName+".mtav").getPath();
//        if (!"/".equals(File.separator)) {
//            filePath = StringUtils.replace(StringUtils.strip(filePath, "/"), "/", File.separator);
//        }
//        log.info("camera file path is {} !", filePath);
//        int version = jsonObject.getIntValue("encrypt_version");
//        if ("LocalRecordStream".equalsIgnoreCase(cmd)) {
//            try {
//                new NVRSenderClient().connect(port, host, din, subdin, streamId, recordHandler, token, stream_en_key, sm4Vector, filePath, version);
//            } catch (Exception e) {
//                log.error(e);
//            }
//        } else if ("StartPushStream".equalsIgnoreCase(cmd)) {
//
//            if (IOTLogin.DO_CONNECTED.get(key) == null) {
//                log.info("camrea {} start push to welink", key);
//                IOTLogin.DO_CONNECTED.put(key, true);
//                new PBPushClientRunnable(din, subdin, streamId, key, stream_en_key, sm4Vector, token, host, port, filePath).run();
//            }
//        } else if ("ClosePushStream".equalsIgnoreCase(cmd)) {
//            CameraDataSendHandler cameraDataSendHandler = IOTLogin.CHANNEL_CONNECT_MAP.get(key);
//            if (cameraDataSendHandler != null) cameraDataSendHandler.disConnect();
//            log.info("close {} camera video stream!", key);
//        }
//
//    }

}
